package com.ming.pojo.vo;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.ming.enums.ErrorCode;
import lombok.Data;
import lombok.experimental.UtilityClass;

import java.io.Serializable;

/**
 * 统一响应结果封装
 *
 * @author ming
 * @version 1.0
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 响应码
     */
    private Integer code;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 时间戳
     */
    private Long timestamp;

    /**
     * 请求追踪ID
     */
    private String traceId;

    /**
     * 私有构造函数
     */
    private Result() {
        this.timestamp = System.currentTimeMillis();
    }

    /**
     * 私有构造函数
     *
     * @param code    响应码
     * @param message 响应消息
     */
    private Result(Integer code, String message) {
        this();
        this.code = code;
        this.message = message;
    }

    /**
     * 私有构造函数
     *
     * @param code    响应码
     * @param message 响应消息
     * @param data    响应数据
     */
    private Result(Integer code, String message, T data) {
        this(code, message);
        this.data = data;
    }

    /**
     * 成功响应
     */
    public static <T> Result<T> success() {
        return new Result<>(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage());
    }

    /**
     * 成功响应（带数据）
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMessage(), data);
    }

    /**
     * 成功响应（自定义消息）
     */
    public static <T> Result<T> success(String message) {
        return new Result<>(ErrorCode.SUCCESS.getCode(), message);
    }

    /**
     * 成功响应（自定义消息和数据）
     */
    public static <T> Result<T> success(String message, T data) {
        return new Result<>(ErrorCode.SUCCESS.getCode(), message, data);
    }

    /**
     * 失败响应（错误码）
     */
    public static <T> Result<T> error(ErrorCode errorCode) {
        return new Result<>(errorCode.getCode(), errorCode.getMessage());
    }

    /**
     * 失败响应（错误码和数据）
     */
    public static <T> Result<T> error(ErrorCode errorCode, T data) {
        return new Result<>(errorCode.getCode(), errorCode.getMessage(), data);
    }

    /**
     * 失败响应（错误码和自定义消息）
     */
    public static <T> Result<T> error(ErrorCode errorCode, String message) {
        return new Result<>(errorCode.getCode(), message);
    }

    /**
     * 失败响应（错误码、自定义消息和数据）
     */
    public static <T> Result<T> error(ErrorCode errorCode, String message, T data) {
        return new Result<>(errorCode.getCode(), message, data);
    }

    /**
     * 失败响应（响应码和消息）
     */
    public static <T> Result<T> error(Integer code, String message) {
        return new Result<>(code, message);
    }

    /**
     * 失败响应（响应码、消息和数据）
     */
    public static <T> Result<T> error(Integer code, String message, T data) {
        return new Result<>(code, message, data);
    }

    /**
     * 失败响应（仅消息，使用默认错误码500）
     */
    public static <T> Result<T> error(String message) {
        return new Result<>(ErrorCode.INTERNAL_SERVER_ERROR.getCode(), message);
    }

    /**
     * 判断响应是否成功
     */
    public boolean isSuccess() {
        return ErrorCode.SUCCESS.getCode() == this.code;
    }

    /**
     * 设置追踪ID
     */
    public Result<T> traceId(String traceId) {
        this.traceId = traceId;
        return this;
    }

    /**
     * 转换为无数据类型的Result
     */
    @SuppressWarnings("unchecked")
    public Result<Void> withoutData() {
        Result<Void> result = new Result<>();
        result.code = this.code;
        result.message = this.message;
        result.timestamp = this.timestamp;
        result.traceId = this.traceId;
        return result;
    }

    /**
     * 结果构建器
     */
    public static class Builder<T> {
        private Integer code;
        private String message;
        private T data;
        private String traceId;

        public Builder<T> code(Integer code) {
            this.code = code;
            return this;
        }

        public Builder<T> message(String message) {
            this.message = message;
            return this;
        }

        public Builder<T> data(T data) {
            this.data = data;
            return this;
        }

        public Builder<T> traceId(String traceId) {
            this.traceId = traceId;
            return this;
        }

        public Result<T> build() {
            Result<T> result = new Result<>();
            result.code = this.code;
            result.message = this.message;
            result.data = this.data;
            result.timestamp = System.currentTimeMillis();
            result.traceId = this.traceId;
            return result;
        }
    }

    /**
     * 创建构建器
     */
    public static <T> Builder<T> builder() {
        return new Builder<>();
    }
}